import { useCallback, useEffect, useState } from "react";

export type AsyncReturn<T> = {
  loading: boolean;
  error?: Error | null;
  value?: T;
};

export default function useAsync<T>(
  callback: () => Promise<T>,
  dependencies: unknown[] = []
): AsyncReturn<T> {
  const [loading, setLoading] = useState(true);
  const [error, setError] = useState<Error>();
  const [value, setValue] = useState<T | undefined>();

  const callbackMemoized = useCallback(() => {
    setLoading(true);
    setError(undefined);
    setValue(undefined);
    callback()
      .then((result) => setValue(result))
      .catch((err) => setError(err))
      .finally(() => setLoading(false));
  }, [...dependencies]);

  useEffect(() => {
    callbackMemoized();
  }, [callbackMemoized]);

  return { loading, error, value };
}
